package com.sfac.springboot.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @Description MyAop
 * @Author JiangHu
 * @Date 2022/8/22 14:39
 */
@Aspect
@Component
public class MyAop {

	public final static Logger LOGGER = LoggerFactory.getLogger(MyAop.class);

	@Pointcut("execution(public * com.sfac.springboot.modules.*.controller.*.*(..))")
	@Order(1)
	public void controllerPointcut() {};

	@Pointcut("@annotation(com.sfac.springboot.aop.MyAnnotation)")
	@Order(1)
	public void annotationPointcut() {};

	@Before(value = "controllerPointcut()")
	public void beforeControllerAop(JoinPoint joinPoint) {
		LOGGER.debug("==== Before controller ====");
		ServletRequestAttributes attr =
				(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attr.getRequest();
		LOGGER.debug(String.format("uri: %s", request.getServletPath()));
		LOGGER.debug(String.format("method: %s", request.getMethod()));
		LOGGER.debug(String.format("method: %s", joinPoint.getSignature().getName()));
	}

	@Around(value = "controllerPointcut()")
	public Object aroundControllerAop(ProceedingJoinPoint proceedingJoinPoint)
			throws Throwable {
		LOGGER.debug("==== Around controller ====");
		return proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
	}

	@After(value = "controllerPointcut()")
	public void afterControllerAop(JoinPoint joinPoint) {
		LOGGER.debug("==== After controller ====");
	}

	@Around(value = "annotationPointcut()")
	public Object aroundAnnotationAop(ProceedingJoinPoint proceedingJoinPoint)
			throws Throwable {
		long start = System.currentTimeMillis();
		Object obj = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
		long end = System.currentTimeMillis();
		LOGGER.debug(String.format("Call method time: %s", (end - start)));
		return obj;
	}
}
